package com.magenta.maxoptra.abstractions.util;

import java.util.List;
import java.util.Map;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;

/**
 * Utilities for javax.lang.model.element and javax.lang.model.type packages.
 * @author ivictus
 *
 */
public class Types {

	private Types () {}

    public static String getPackageName(Element e) {
        while ( e.getKind() != ElementKind.PACKAGE ) {
        	e = e.getEnclosingElement();
        }
        return ((PackageElement)e).getQualifiedName().toString();
    }

    public static String getClassName(Element e) {
    	if ( e.getKind() == ElementKind.CLASS ) {
    		return ((TypeElement) e).getQualifiedName().toString();
    	}
    	return null;
    }

	public static Object getAnnotationFieldValue(Element element,
			TypeElement typeElement, String annotationFieldName) {
		List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
		//SEARCH MIRROR FOR TYPE ELEMENT
		AnnotationMirror mirrorOfTypeElement = null;
		for ( AnnotationMirror annotationMirror : annotationMirrors ) {
			if ( annotationMirror.getAnnotationType().equals(typeElement.asType()) ) {
				mirrorOfTypeElement = annotationMirror;
			}
		}
		//ACCESS TO ATTRIBUTE
		if ( mirrorOfTypeElement != null ) {
			for ( Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : mirrorOfTypeElement.getElementValues().entrySet() ) {
				if ( entry.getKey().getSimpleName().contentEquals(annotationFieldName) ) {
					return entry.getValue().getValue();
				}
			}
		}
		return null;
	}

}
